﻿using HomagChina.CCHCS.DataTypeModel;
using HomagGroup.Base.UI;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;

using static HomagChina.CCHCS.ProcessResourceInternal;

namespace HomagChina.CCHCS
{
    internal class ContainersCreator : NotifyPropertyChangedBase
    {
        public ObservableCollection<Proxy.LayerInfo> BoardsInContainerList { get; set; }

        public ObservableCollection<Canvas> ContainersList { get; set; } = new ObservableCollection<Canvas>();

        public event EventHandler LayerSelectedEventHandler;

        private const double RealLength = 3000;
        private const double RealHeight = 70;

        private const double LengthScale = 0.09;
        private const double HeightScale = 0.34;

        private static readonly double DisplayLength = MmToLengthDip(RealLength); // 3000mm  270 DIP

        private static readonly double DisplayLayerHeight = MmToHeightDip(RealHeight); // 70mm  24.5 DIP
        private const double ContainerSpacing = 22; // 容器间距

        private const double TitleHeight = 30; // 标题高度
        private const double LayerMarginLeft = 30; // 层级左边距
        private const double LayerLabelWidth = 30; // 标签宽度

        // 毫米转DIP方法
        private static double MmToLengthDip(double mm) => mm * LengthScale; // 长度方向转换

        private static double MmToHeightDip(double mm) => mm * HeightScale; // 高度方向转换

        private static double realityLayerLength(double mm) => mm * 0.08;

        public Canvas Element { get; set; }

        public ContainersCreator()//Canvas element, ObservableCollection<LayerInfo> boardsInContainerList
        {
            //BoardsInContainerList = new ObservableCollection<LayerInfo>(boardsInContainerList);
            //this.Element = element;
            //CreateDrawingContainers();
            //AddBoardsToContainers();
        }

        public void Init(Canvas element, ObservableCollection<Proxy.LayerInfo> boardsInContainerList)
        {
            BoardsInContainerList = boardsInContainerList;
            this.Element = element;
            CreateDrawingContainers();
            AddBoardsToContainers();
        }

        private void CreateDrawingContainers()
        {
            Element.Children.Clear();
            for (int i = 0; i < 4; i++)
            {
                double startX = ContainerSpacing + (i + 1) * (DisplayLength + ContainerSpacing);

                Canvas container = CreateContainer(i);

                Canvas.SetLeft(container, startX);
                Canvas.SetTop(container, 10);

                //if (Element.Children.Count >= 4)
                //{
                //    Element.Children.RemoveAt(0);
                //}
                Element.Children.Add(container);
            }
        }

        private Canvas CreateContainer(int index)
        {
            double totalHeight = TitleHeight + 20 * DisplayLayerHeight;

            var container = new Canvas
            {
                Uid = (index + 1).ToString(),
                Width = DisplayLength,
                Height = totalHeight
            };

            AddTitle($"# Containers {index + 1}", container);
            AddLayers(container);

            return container;
        }

        private void AddLayers(Panel container)
        {
            ContainersList.Clear();
            for (int i = 0; i < 20; i++)
            {
                int layerNumber = 20 - i;
                double positionY = TitleHeight + i * DisplayLayerHeight;
                Canvas layerCanvas = new Canvas
                {
                    Uid = layerNumber.ToString(),
                    Width = DisplayLength - LayerMarginLeft,
                    Height = DisplayLayerHeight,
                    Background = Brushes.Transparent
                };

                ContainersList.Add(layerCanvas);
                AddLayerBorders(layerCanvas);

                Canvas.SetLeft(layerCanvas, LayerMarginLeft);
                Canvas.SetTop(layerCanvas, positionY);
                container.Children.Add(layerCanvas);
                AddLayerLabel(layerNumber, positionY, container);
                layerCanvas.MouseLeftButtonDown += (sender, e) => LayerSelectedEventHandler?.Invoke(sender, e);
            }
        }

        private void AddLayerBorders(Canvas canvas)
        {
            canvas.Children.Add(new Path
            {
                Data = new LineGeometry(new Point(0, 0), new Point(0, canvas.Height)),
                Stroke = Brushes.Black,
                StrokeThickness = 1
            });
            canvas.Children.Add(new Path
            {
                Data = new LineGeometry(new Point(canvas.Width, 0), new Point(canvas.Width, canvas.Height)),
                Stroke = Brushes.Black,
                StrokeThickness = 1
            });
            canvas.Children.Add(new Path
            {
                Data = new LineGeometry(new Point(0, canvas.Height), new Point(canvas.Width, canvas.Height)),
                Stroke = Brushes.Black,
                StrokeThickness = 1
            });
        }

        private void AddLayerLabel(int number, double positionY, Panel container)
        {
            var label = new Label
            {
                Content = $"L{number}",
                Width = LayerLabelWidth,
                Height = DisplayLayerHeight + 1,
                Background = Brushes.LightGray,
                FontSize = 12,
                VerticalContentAlignment = VerticalAlignment.Center,
                HorizontalContentAlignment = HorizontalAlignment.Left
            };

            Canvas.SetLeft(label, 0);
            Canvas.SetTop(label, positionY);
            container.Children.Add(label);
        }

        private void AddTitle(string title, Panel container)
        {
            var titleLabel = new Label
            {
                Content = title,
                Width = DisplayLength + 1,
                Height = TitleHeight,
                Background = GetHexadecimalColor("#B7C2CB"),
                Foreground = Brushes.Black,
                FontSize = 18,
                FontWeight = FontWeights.Bold,
                VerticalContentAlignment = VerticalAlignment.Center,
                HorizontalContentAlignment = HorizontalAlignment.Center
            };

            Canvas.SetTop(titleLabel, 0);
            container.Children.Add(titleLabel);
        }

        private void AddBoardsToContainers()
        {
            foreach (var board in BoardsInContainerList)
            {
                var container = Element.Children.OfType<Canvas>().FirstOrDefault(c => c.Uid == board.RSShelfOrder.ToString());

                if (container != null)
                {
                    var layer = container.Children.OfType<Canvas>().FirstOrDefault(l => l.Uid == board.RSLayerNum.ToString());

                    if (layer != null)
                    {
                        // 计算板件尺寸
                        double width = board.PackRt90 ? realityLayerLength((double)board.Width) : realityLayerLength((double)board.Length);
                        double height = MmToHeightDip((double)board.Thickness);

                        // 计算水平居中位置
                        double left = (realityLayerLength((double)board.RSCenterX) - width / 2) >= 0 ? (realityLayerLength((double)board.RSCenterX) - width / 2) : 0;
                        double top = (DisplayLayerHeight - height) / 2;
                        //double top = (DisplayLayerHeight - height) - (MmToHeightDip(3) * ((double)board.ZCoor / 18));
                        //var fill = board.ZCoor == 18 ? GetHexadecimalColor("#ff9300") : GetHexadecimalColor("#5b9bd5");
                        var rect = new Rectangle
                        {
                            Width = width,
                            Height = height,
                            Fill = GetHexadecimalColor("#ff9300"),
                            Stroke = Brushes.Black,
                            StrokeThickness = 0.5,
                            RadiusX = 2,
                            RadiusY = 2
                        };

                        Canvas.SetLeft(rect, left);
                        Canvas.SetTop(rect, top);
                        layer.Children.Add(rect);
                    }
                }
            }
        }
    }
}